package com.gitee.apanlh.util.algorithm.digest;

import com.gitee.apanlh.exp.DigestException;
import com.gitee.apanlh.util.valid.Assert;

import java.security.MessageDigest;

/**
 * 	使用JDK默认自带摘要算法
 * 	<br>非线程安全类
 * 	
 * 	@author Pan
 */
public abstract class JdkDigestAbstract extends DigestAbstract implements CheckDigestType {
	
	/** 摘要类型 */
	private DigestType digestType;
	/** 摘要器 */
	private MessageDigest messageDigest;
	
	/**
	 * 	默认构造函数
	 * 	
	 * 	@author Pan
	 */
	JdkDigestAbstract() {
		super();
	}
	
	/**
	 * 	构造函数
	 * 	<br>加载指定类型
	 * 	
	 * 	@author Pan
	 * 	@throws DigestException 如果未找到对应摘要算法则抛出
	 */
	JdkDigestAbstract(DigestType digestType) {
		this.digestType = digestType;
		generatorDigest();
	}
	
	@Override
	public void check() throws DigestException {
		throw new AbstractMethodError("not found check method");
	}
	
	/**
	 * 	生成摘要器
	 * 	
	 * 	@author Pan
	 * 	@throws DigestException 如果未找到对应摘要算法则抛出
	 */
	void generatorDigest() {
		check();
		try {
			this.messageDigest = MessageDigest.getInstance(digestType.getAlgorithm());
		} catch (Exception e) {
			throw new DigestException(e.getMessage());
		}
	}
	
	/**	
	 * 	计算hash摘要
	 * 	<br>用于子类中实现指定摘要算法
	 * 	<br>比如SHA中默认指定SHA256算法或自定义hash算法
	 * 	
	 * 	@author Pan
	 * 	@param 	content				内容
	 * 	@return	byte[]				Hash后的内容
	 * 	@throws DigestException  	摘要计算错误时抛出
	 */
	@Override
	public byte[] hash(byte[] content) {
		Assert.isNotEmpty(content);
		
		try {
			this.messageDigest.update(content);
			return this.messageDigest.digest();
		} catch (Exception e) {
			throw new DigestException(e.getMessage());
		}
	}

	/**	
	 * 	获取摘要类型
	 * 	
	 * 	@author Pan
	 * 	@return	DigestType
	 */
	public DigestType getDigestType() {
		return this.digestType;
	}

	/**	
	 * 	设置摘要类型
	 * 	
	 * 	@param digestType	摘要类型
	 */
	public void setDigestType(DigestType digestType) {
		this.digestType = digestType;
	}
}
